﻿using System;
using System.Data;
using System.Configuration;
using System.Linq;
using System.Web;
using System.Web.Security;
using System.Web.UI;
using System.Web.UI.HtmlControls;
using System.Web.UI.WebControls;
using System.Web.UI.WebControls.WebParts;
using System.Xml.Linq;
using System.Collections.Generic;
using System.Text;
using System.Xml;

namespace RegexLib.Web.Models.Web.Admin
{
	/// <summary>
	/// 管理员权限。
	/// </summary>
	public enum RxAdminPermissions
	{
		/// <summary>
		/// 包含其他所有权限，是最高级的权限。
		/// </summary>
		All,
	}

	/// <summary>
	/// 表示管理员权限集合。
	/// </summary>
	public class RxAdminPermissionSet : List<RxAdminPermissions>
	{
		public RxAdminPermissionSet(params RxAdminPermissions[] permissions)
		{
			this.AddRange(permissions);
		}

		public override string ToString()
		{
			if (this.Count <= 0)
				return "";

			StringBuilder sb = new StringBuilder();
			sb.Append(this[0].ToString());

			for (int i = 1; i < this.Count; i++)
			{
				sb.Append(",");
				sb.Append(this[i].ToString());
			}
			return sb.ToString();
		}

		/// <summary>
		/// 从字符串中解析权限集。
		/// </summary>
		/// <param name="s"></param>
		/// <returns></returns>
		public static RxAdminPermissionSet Parse(string s)
		{
			string[] ps = s.Split(new[] { ',' });
			var permissions = ps.Select(p => (RxAdminPermissions)Enum.Parse(typeof(RxAdminPermissions), p)).ToArray();
			return new RxAdminPermissionSet(permissions);
		}
	}

	/// <summary>
	/// 表示管理员。
	/// </summary>
	public static class RxAdmin
	{
		public static bool IsAdmin()
		{
			var user = RxMembership.GetCurrentUser();
			if (user == null)
				return false;

			var adminPermissions = GetAdminPermissions();
			return adminPermissions.ContainsKey(user.UserId);
		}

		/// <summary>
		/// 检查当前登录用户的管理员权限。
		/// </summary>
		/// <param name="permissions"></param>
		public static void CheckPermission(RxAdminPermissions permissions)
		{
			var user = RxMembership.GetCurrentUser();
			if (user == null)
				throw new RxAdminNotLoggedInException();

			var adminPermissions = GetAdminPermissions();
			if (!adminPermissions.ContainsKey(user.UserId))
				throw new RxNotAdminException();

			var p = adminPermissions[user.UserId];
			if (p.Contains(RxAdminPermissions.All))
				return;

			if (!p.Contains(permissions))
				throw new RxAdminPermissionException();
		}

		/// <summary>
		/// 判断当前登录用户是否具有指定管理权限。
		/// </summary>
		/// <param name="permissions"></param>
		/// <returns></returns>
		public static bool HasPermission(RxAdminPermissions permissions)
		{
			var user = RxMembership.GetCurrentUser();
			if (user == null)
				return false;

			var adminPermissions = GetAdminPermissions();
			if (!adminPermissions.ContainsKey(user.UserId))
				return false;

			var p = adminPermissions[user.UserId];
			if (p.Contains(RxAdminPermissions.All))
				return true;

			return p.Contains(permissions);
		}

		/// <summary>
		/// 管理员权限配置文件路径。
		/// </summary>
		const string AdminSettingsPath = "~/App_Data/Admins.xml";

		/// <summary>
		/// 从xml配置文件中获取管理员权限配置。（xml文件位于~/App_Data/Admins.xml。）
		/// </summary>
		/// <returns></returns>
		static Dictionary<Guid, RxAdminPermissionSet> GetAdminPermissions()
		{
			// 1 尝试从缓存中读取。
			Dictionary<Guid, RxAdminPermissionSet> permissions = RxAppDataCache.Get<Dictionary<Guid, RxAdminPermissionSet>>(AdminSettingsPath);
			if (permissions != null)
				return permissions;

			// 2 从xml文件中读取。
			permissions = new Dictionary<Guid, RxAdminPermissionSet>();
			XmlDocument xdoc = new XmlDocument();
			xdoc.Load(HttpContext.Current.Server.MapPath(AdminSettingsPath));
			var xnodes = xdoc.SelectNodes("/admins/admin");
			foreach (XmlNode xn in xnodes)
			{
				Guid id = new Guid(xn.Attributes["id"].Value);
				RxAdminPermissionSet pset = RxAdminPermissionSet.Parse(xn.Attributes["permissions"].Value);
				permissions.Add(id, pset);

			}

			// 3 放入缓存。
			RxAppDataCache.Set<Dictionary<Guid, RxAdminPermissionSet>>(AdminSettingsPath, permissions);
			return permissions;
		}
	}

	/// <summary>
	/// 所有管理相关异常的基类。
	/// </summary>
	public class RxAdminException : Exception
	{
	}

	/// <summary>
	/// 表示管理员尚未登录。
	/// </summary>
	public class RxAdminNotLoggedInException : RxAdminException
	{
	}

	/// <summary>
	/// 表示当前登录用户并非管理员。
	/// </summary>
	public class RxNotAdminException : RxAdminException
	{
	}

	/// <summary>
	/// 表示当前管理员权限不够。
	/// </summary>
	public class RxAdminPermissionException : RxAdminException
	{
	}
}
